package com.whg.opengl.shape;

import android.opengl.GLES20;
import android.opengl.Matrix;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;

/**
 * author : Whg
 * e-mail : guanhuawei@ksjgs.com
 * date   : 2019-10-1109:19
 * desc   :
 * version: 1.0  三角形
 * 1.初始化  2.渲染
 * Stay hungry,stay foolish.
 */
public class Triangle {

    /**
     * opengl套路：
     * 1.创建顶点数组
     * 2.自己写顶点着色器和边元着色器
     * 3.将java声明的顶点数组，颜色数组，通过类似于jni接口传递给gl语言的变量
     */

    static float triangleCoords[] = {
            0.5f, 0.5f, 0.0f,
            -0.5f, -0.5f, 0.0f,
            0.5f, -0.5f, 0.0f
    };

    float color[] = {1.0f, 1.0f, 1.0f, 1.0f};

    private float[] mViewMatrix = new float[16];
    private float[] mProjectMatrix = new float[16];
    private float[] mMVPMatrix = new float[16];


    private int mProgram;
    private FloatBuffer vertextBuffer;

    // java反射gl

    //定点着色器的gl语法
    private String vertextShaderCode =
            "attribute vec4 vPosition;" +
                    "uniform mat4 vMatrix;" +
                    "void main(){" +
                    "gl_Position=vMatrix*vPosition;" +
                    "}";

    //片元着色器的gl语法
    private String fragmentShaderCode =
            "precision mediump float;" +
                    "uniform vec4 vColor;" +
                    "void main(){" +
                    "gl_FragColor=vColor;" +
                    "}";

    public Triangle() {
        ByteBuffer bb = ByteBuffer.allocateDirect(triangleCoords.length * 4);
        bb.order(ByteOrder.nativeOrder());
        //转换成floatbuffer  跟gpu沟通的桥梁
        vertextBuffer = bb.asFloatBuffer();
        //推送给gpu
        vertextBuffer.put(triangleCoords);
        vertextBuffer.position(0);

        //创建定点着色器  并且在gpu里面编译
        int shader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
        GLES20.glShaderSource(shader, vertextShaderCode);
        GLES20.glCompileShader(shader);


        //创建片元着色器  并且在gpu里面编译
        int fragmentShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
        GLES20.glShaderSource(fragmentShader, fragmentShaderCode);
        GLES20.glCompileShader(fragmentShader);

        //将定点着色器和片云着色器统一管理
        mProgram = GLES20.glCreateProgram();
        GLES20.glAttachShader(mProgram, shader);
        GLES20.glAttachShader(mProgram, fragmentShader);

        //连接到着色器程序
        GLES20.glLinkProgram(mProgram);
    }

    /**
     * 渲染
     *
     * @param gl10
     */
    public void onDrawFrame(GL10 gl10) {
        GLES20.glUseProgram(mProgram);
        int mMatrixHandler = GLES20.glGetUniformLocation(mProgram, "vMatrix");
        GLES20.glUniformMatrix4fv(mMatrixHandler, 1, false, mMVPMatrix, 0);


        //指针  native的指针   gpu的某个内存区域  vPosition
        int mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
        //允许对变量的读写
        GLES20.glEnableVertexAttribArray(mPositionHandle);
        GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, 3 * 4, vertextBuffer);


        int mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
        GLES20.glUniform4fv(mColorHandle, 1, color, 0);
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);

        //禁用
        GLES20.glDisableVertexAttribArray(mPositionHandle);

    }

    public void onSurfaceChanged(GL10 gl10, int width, int height) {
        float ratio = (float) width / height;

        //投影矩阵
        Matrix.frustumM(mProjectMatrix, 0, -ratio, ratio, -1, 1, 3, 120);

        Matrix.setLookAtM(mViewMatrix, 0, 0, 0, 7,//摄像机的坐标
                0f, 0f, 0f,//目标物的中心坐标
                0f, 1f, 0f);//相机方向
        //计算变换矩阵
        Matrix.multiplyMM(mMVPMatrix, 0, mProjectMatrix, 0, mViewMatrix, 0);
    }
}

